package com.qf.utils;


import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Component //将当前类交给Spring管理
public class JwtUtils {


    private final RedisUtil redisUtil;
    // 令牌自定义标识
    @Value("${token.header}")
    private String header;

    // 令牌秘钥
    @Value("${token.secret}")
    private String secret;

    // 令牌有效期（默认60分钟）
    @Value("${token.expireTime}")
    private int expireTime;

    public JwtUtils(RedisUtil redisUtil) {
        this.redisUtil = redisUtil;
    }

    //生成jwt令牌
    public String createToken(Map<String, Object> claims) {

        //构建jwt
        String token = Jwts.builder()
                .setClaims(claims) //设置载荷
                .signWith(SignatureAlgorithm.HS256, secret.getBytes(StandardCharsets.UTF_8)) //使用指定算法设置签名
                //.setExpiration(new Date(System.currentTimeMillis() + expireTime * 1000 * 60)) //设置密钥过期时间
                .compact();// 生成最终的JWT字符串
        return token;
    }

    //后端接收前端发送的token，请求头中获取
    public String getToken(HttpServletRequest request) {
        String token = request.getHeader(header);
        System.out.println(request.getHeader(header));
        if (StringUtils.hasText(token)) {
            return token; 
        }
        return null;
    }

    //解析从前端请求头中拿到的token

    public Claims parseToken(String token) {
        try {
            Claims claims = Jwts.parser()
                    .setSigningKey(secret.getBytes(StandardCharsets.UTF_8))
                    .parseClaimsJws(token).getBody(); //解析并验证token

            return claims;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    /**
     * 验证token，验证此次请求token有无超时
     */

    public void validateToken(String token) {
            Claims claims = Jwts.parser()
                    .setSigningKey(secret.getBytes(StandardCharsets.UTF_8))
                    .parseClaimsJws(token).getBody();
            //获取claims中的uuid
            Object uuid = claims.get("uuid");
            //从redis中取出uuid
            Object redisToken = redisUtil.getCacheObject("user:key:" + uuid);
//            System.out.println("redis中取出："+redisToken);
//            System.out.println("传过来的"+token);
//            System.out.println(!redisToken.equals(token));
            if (redisToken == null || !redisToken.equals(token)) {
                throw new AccessDeniedException("token验证失败");
            }
    }

    /**
     * 刷新令牌存活时间
     */
    public void refreshToken(String token) {
        Claims claims = Jwts.parser()
                .setSigningKey(secret.getBytes(StandardCharsets.UTF_8))
                .parseClaimsJws(token).getBody();
        Object uuid = claims.get("uuid");

        redisUtil.setCacheObject("user:key:" + uuid, token, expireTime, TimeUnit.MINUTES);
    }

}
